Skip to content

FE-1569: Add durable Brunch storage and telemetry - #9487

Open
lunelson wants to merge 1 commit into
ln/fe-1569-brunch-agent-containerfrom
ln/fe-1569-brunch-agent-deployment
Open

FE-1569: Add durable Brunch storage and telemetry#9487
lunelson wants to merge 1 commit into
ln/fe-1569-brunch-agent-containerfrom
ln/fe-1569-brunch-agent-deployment

Conversation

@lunelson

@lunelson lunelson commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

🌟 What is the purpose of this PR?

Add the runtime behavior needed to take the containerized Brunch service to the application-to-infrastructure deployment boundary: durable Flue Postgres state, content-free operational telemetry, and explicit diagnostics for restricted deployment and recovery.

This PR does not claim that Brunch is deployed. The downstack container PR publishes to ECR and GHCR, but no Brunch ECS service, RDS target, hosted collector, restricted ingress, or deployment owner is confirmed, so Mission 8 remains open at its required handoff boundary.

🔗 Related links

🚫 Blocked by

  • Infrastructure owner confirms and provisions the Brunch ECS, RDS/IAM, collector, restricted ingress, and deployment-owner targets.
  • The remote Mission 8 proof matrix passes against one immutable image digest.

🔍 What does this change?

  • Replaces deployed SQLite with fail-closed @flue/postgres persistence using dedicated fields, verified TLS, RDS IAM tokens per physical connection, and a runtime-password fallback.
  • Adds content-free Flue and Node OpenTelemetry export over OTLP/gRPC with graceful lifecycle flush and operational database-failure spans.
  • Adds RDS IAM and restricted deployment probes plus a disposable TLS Postgres/OTel container smoke.
  • Documents runtime configuration, ingress restrictions, local proof, GHCR publication, and the outstanding infrastructure handoff.
🏗️ Agent notes

The branch authority is libs/@hashintel/brunch-agent/MISSION.md. It records Mission 8 as live but stopped at the explicit application-to-infrastructure handoff boundary.

Locally established:

  • fail-closed production configuration and Flue Postgres migration before listen;
  • IAM-token callback refresh, transaction pinning/rollback, TLS verification, and static-password fallback;
  • content-free OTLP traces, logs, and metrics with graceful shutdown;
  • disposable TLS Postgres and OTel collector integration smoke.

Still open:

  • real task-role/RDS IAM connectivity;
  • restricted streamed Anthropic/tool execution;
  • in-place and cross-host replacement recovery;
  • bounded provider/database/stream failure inspection in the hosted telemetry backend;
  • singleton replacement, rollback, and owner acceptance.

The downstack PR registers ECR and GHCR publication with no ECS target. Infrastructure provisioning and remote proof remain outside this local application artifact.

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • does not modify any publishable blocks or libraries, or modifications do not need publishing

📜 Does this require a change to the docs?

The changes in this PR:

  • require changes to docs which are made as part of this PR

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • affected the execution graph, and the turbo.json files have been updated to reflect this

⚠️ Known issues

  • Brunch is not deployed; the deploy catalog publishes to ECR and GHCR but has no ECS target.
  • The local Docker smoke uses the runtime-password path; the real task-role RDS IAM probe remains unrun.
  • /health proves process liveness only. Database connection and migration gate startup before the server listens.
  • Public identity, authorization, rate/spend controls, retention/deletion policy, backup restoration, and multi-replica ownership remain outside this restricted singleton threshold.

🐾 Next steps

  • Provision and record the ECS, RDS/IAM, secret, collector, ingress, health, timeout, drain, and ownership contract from the deployment handoff.
  • Run the remote proof matrix with one immutable digest and update this PR, Mission 8, and FE-1569 with observed results.

🛡 What tests cover this?

  • 80 Vitest unit tests covering configuration, IAM token refresh, Postgres transactions, health, telemetry lifecycle, artifact wiring, and existing Brunch behavior.
  • TypeScript typecheck, application build, and Oxlint with eight pre-existing warnings and no errors.
  • The previously completed Docker integration smoke covers TLS Postgres migration/startup, fail-closed configuration, OTel export, non-root identity, packaged resources, repository immutability, health, and graceful shutdown.

❓ How to test this?

  1. Run yarn workspace @apps/brunch-agent lint:tsc.
  2. Run yarn workspace @apps/brunch-agent test:unit.
  3. Run yarn workspace @apps/brunch-agent build.
  4. Run turbo run test:docker --filter @apps/brunch-agent with Docker available.
  5. After infrastructure exists, follow apps/brunch-agent/README.md and the Mission 8 deployment handoff for the IAM and remote smoke commands.

📹 Demo

No visual UI change. The proof artifact is the production container and its deployment diagnostics.

@vercel

vercel Bot commented Sep 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
hash Ready Ready Preview Sep 5, 2026 2:19pm UTC
hashdotdesign-tokens Ready Ready Preview Sep 5, 2026 2:19pm UTC
petrinaut Ready Ready Preview Sep 5, 2026 2:19pm UTC
petrinaut-docs Ready Ready Preview Sep 5, 2026 2:19pm UTC

Request Review

@github-actions github-actions Bot added area/deps Relates to third-party dependencies (area) area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team area/tests New or updated tests area/apps labels Sep 1, 2026
Comment thread apps/brunch-agent/src/postgres.ts Fixed
@codspeed-hq

codspeed-hq Bot commented Sep 1, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

⚠️ 6 benchmarks measured no execution time

Nothing ran under measurement, usually because the compiler removed the code under test. These results are not comparable, so they count as unchanged.

Preventing compiler optimizations

✅ 98 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
⚠️ as_constant < 1 ns < 1 ns N/A
⚠️ constant_equal < 1 ns < 1 ns N/A
⚠️ constant_not_equal < 1 ns < 1 ns N/A
⚠️ access < 1 ns < 1 ns N/A
⚠️ runtime_equal < 1 ns < 1 ns N/A
⚠️ runtime_not_equal < 1 ns < 1 ns N/A

Comparing ln/fe-1569-brunch-agent-deployment (a4a2bae) with main (4854d5f)1

Open in CodSpeed

Footnotes

  1. No successful run was found on ln/fe-1569-brunch-agent-container (3f13430) during the generation of this report, so main (4854d5f) was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

lunelson commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@TimDiekmann TimDiekmann left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good if we could isolate the Dockerfile changes into an own PR. The changes to .github/workflows/deploy.yml will make sure that the build is covered in CI and will upload it on merge to main. I will make sure that a ECR is set up where we can upload the image to and extend the definition with that.

Comment thread apps/brunch-agent/package.json
Comment thread apps/brunch-agent/docker/Dockerfile
@lunelson
lunelson changed the base branch from ln/fe-1563-redesign-runbook-workpiece to graphite-base/9487 September 2, 2026 11:12
@lunelson
lunelson force-pushed the ln/fe-1569-brunch-agent-deployment branch from 157730c to a118473 Compare September 2, 2026 11:12
@lunelson
lunelson changed the base branch from graphite-base/9487 to ln/fe-1569-brunch-agent-container September 2, 2026 11:12
@lunelson lunelson changed the title FE-1569: Containerize and safely deploy Brunch on HASH infrastructure FE-1569: Add durable Brunch storage and telemetry Sep 2, 2026
@vercel
vercel Bot temporarily deployed to Preview – petrinaut September 2, 2026 11:13 Inactive
@cursor

cursor Bot commented Sep 4, 2026

Copy link
Copy Markdown

PR Summary

High Risk
Changes production data path (Postgres/IAM auth), mandatory telemetry, and startup failure modes for the deployed chat service; misconfiguration or pool/auth bugs would block readiness or lose conversation durability.

Overview
Prepares the containerized Brunch app for HASH deployment by making production conversation state durable in Postgres and wiring content-free operational telemetry, plus CLIs and smokes to validate the boundary before ECS exists.

Persistence: db.ts now loads a fail-closed production contract (BRUNCH_POSTGRES_*): verified TLS, 10s connection timeout, RDS IAM tokens per physical connection (or password fallback), and rejection of DATABASE_URL / local SQLite env vars. Non-production still uses SQLite. A pg runner backs @flue/postgres and ties pool shutdown to telemetry disposal.

Telemetry: OpenTelemetry moves behind telemetry-bootstrap.ts (imported before routes/DB). Production requires HASH_OTLP_ENDPOINT; Flue instrumentation stays content: false while traces, logs, and metrics export over OTLP/gRPC. Startup DB failures emit content-free operational spans.

Ops & proof: New scripts include start / start:test, probe:rds-iam, smoke:deployment (streamed turn + persisted history), and test:docker (Postgres + OTel collector smoke). README and a Mission 8 handoff doc spell out env vars, ingress limits (/api/chat only externally), and singleton rollout. Turbo gains test:docker, integration vitest split, and start:* healthcheck wiring.

Reviewed by Cursor Bugbot for commit a4a2bae. Bugbot is set up for automated code reviews on this repo. Configure here.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Moderate issues remain in recovery validation, database timeouts, and Flue telemetry export.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds durable PostgreSQL persistence, RDS IAM support, operational telemetry, and deployment diagnostics for the Brunch service.

Changes:

  • Adds fail-closed PostgreSQL configuration with TLS and IAM/password authentication.
  • Adds OTLP telemetry lifecycle and database-failure reporting.
  • Adds deployment probes, integration tests, and infrastructure handoff documentation.
File summaries
File Review
yarn.lock Locks new database, AWS, and telemetry dependencies.
libs/@hashintel/brunch-agent/MISSION.next.md Updates deployment backlog and planning context.
libs/@hashintel/brunch-agent/MISSION.md Defines the restricted-deployment mission.
libs/@hashintel/brunch-agent/docs/evidence/implementations/mission-8-deployment-handoff.md Records proof status and infrastructure handoff.
apps/brunch-agent/turbo.json Adds telemetry environment and integration-test wiring.
apps/brunch-agent/test/telemetry.test.ts Tests telemetry configuration and disposal.
apps/brunch-agent/test/postgres.test.ts Tests pooling, IAM tokens, transactions, and shutdown.
apps/brunch-agent/test/database-config.test.ts Tests production database validation.
apps/brunch-agent/test/container-smoke.integration.ts Exercises the production container with PostgreSQL and OTel.
apps/brunch-agent/test/build-artifact.test.ts Verifies persistence and telemetry bundle wiring.
apps/brunch-agent/test/architecture/boundaries.integration.ts Registers the telemetry architecture boundary.
apps/brunch-agent/src/telemetry.ts Configures OTLP providers and failure spans. Moderate (1 vote): Flue metrics use the unregistered global meter and are not exported. Moderate (1 vote): Flue also receives no logger, dropping its logs as well as metrics.
apps/brunch-agent/src/telemetry-bootstrap.ts Installs telemetry before application initialization.
apps/brunch-agent/src/rds-iam-probe.ts Adds the two-connection IAM diagnostic.
apps/brunch-agent/src/postgres.ts Implements the Flue PostgreSQL runner. Moderate (1 vote): No connection timeout is configured, allowing database operations and diagnostics to wait indefinitely.
apps/brunch-agent/src/deployment-smoke.ts Adds remote turn and history diagnostics. Moderate (2 votes): Recovery can report success for missing/malformed history, and streamed turns do not require a successful finish.
apps/brunch-agent/src/db.ts Selects PostgreSQL in production and SQLite locally.
apps/brunch-agent/src/database-config.ts Defines fail-closed production database configuration.
apps/brunch-agent/src/app.ts Bootstraps telemetry before route setup.
apps/brunch-agent/README.md Documents runtime and deployment requirements.
apps/brunch-agent/package.json Adds dependencies and operational scripts.
apps/brunch-agent/docs/task-dependencies.json Documents the new task dependencies.
Review details

Suppressed comments (4)

apps/brunch-agent/src/postgres.ts:102

  • A pg pool emits an error event when an idle connection is broken; without a listener, Node treats that event as unhandled and terminates the process. A routine RDS restart or network partition can therefore crash Brunch instead of producing the operational database-failure telemetry added by this PR. Attach a pool error listener and report it through reportDatabaseFailure.
export const createPostgresPool = (
  config: PostgresDatabaseConfig,
  options?: ConnectionOptions,
): Pool => new Pool(createPostgresPoolConfig(config, options));

apps/brunch-agent/src/postgres.ts:200

  • If one pool.connect() resolves and the other rejects, the Promise.all assignment never completes, so clients remains empty and the successful checked-out client is omitted from the finally cleanup. The failed IAM probe then leaks that client and can leave pool.end() waiting indefinitely. Acquire while appending each client (the first remains checked out, so the second is still guaranteed to be a distinct physical connection).
  let clients: PoolClient[] = [];
  try {
    clients = await Promise.all([pool.connect(), pool.connect()]);

apps/brunch-agent/src/postgres.ts:128

  • A transaction that fails while acquiring a pooled connection bypasses the try block, so no database_operation failure span is recorded. This is the exact path taken when Postgres is unavailable during Flue startup/migration, contradicting the operational database-failure telemetry contract. Report and rethrow acquisition failures before entering the transaction body.
      const client = await pool.connect();

apps/brunch-agent/src/postgres.ts:156

  • Both expressions passed to Promise.allSettled are invoked immediately, so telemetry shutdown begins before pool.end() has completed. The unit test only observes synchronous mock side effects and therefore does not enforce the documented “close Postgres, then flush OTel” lifecycle; with a real pool, final database activity can race provider shutdown. Await the Postgres result first, then invoke the telemetry closer while still collecting both failures.
      const results = await Promise.allSettled([pool.end(), afterClose?.()]);
  • Files reviewed: 21/22 changed files
  • Comments generated: 4
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread apps/brunch-agent/src/deployment-smoke.ts Outdated
Comment thread apps/brunch-agent/src/postgres.ts
Comment thread apps/brunch-agent/src/telemetry.ts
Comment thread apps/brunch-agent/src/telemetry.ts Outdated
Comment thread apps/brunch-agent/src/telemetry.ts
Comment thread apps/brunch-agent/src/database-config.ts
Comment thread apps/brunch-agent/src/deployment-smoke.ts
Comment thread apps/brunch-agent/src/postgres.ts
Comment thread apps/brunch-agent/src/postgres.ts Outdated
Comment thread apps/brunch-agent/src/postgres.ts
Comment thread apps/brunch-agent/src/postgres.ts Dismissed
@lunelson

lunelson commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

@TimDiekmann according to my agent, CI is currently blocked here by an unrelated pruning issue:

  • the workflow initially prunes out @rust/hash-repo-chores
  • the Brunch integration test subsequently performs a nested Docker build
  • that build's turbo prune evaluates turbo.json and encounters the missing @rust/hash-repo-chores#build reference

Failing job: https://github.com/hashintel/hash/actions/runs/33872870612/job/101023099113

FWIW, agent thinks the integration workflow likely needs to retain @rust/hash-repo-chores, as the unit workflow already does. Rerunning the job alone will not fix it... Thoughts?

Comment thread apps/brunch-agent/package.json Outdated
Comment thread apps/brunch-agent/package.json Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c079ffb. Configure here.

Comment thread apps/brunch-agent/test/container-smoke.ts
Co-authored-by: Cursor <cursoragent@cursor.com>

Normalize deployment dependency lockfile

Co-authored-by: Cursor <cursoragent@cursor.com>

Publish the Brunch image to GHCR

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Benchmark results

@rust/hash-graph-benches – Integrations

policy_resolution_large

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2002 $$27.3 \mathrm{ms} \pm 296 \mathrm{μs}\left({\color{gray}-2.452 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.43 \mathrm{ms} \pm 20.0 \mathrm{μs}\left({\color{gray}-1.677 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1002 $$12.3 \mathrm{ms} \pm 100 \mathrm{μs}\left({\color{gray}-2.215 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 3314 $$43.4 \mathrm{ms} \pm 479 \mathrm{μs}\left({\color{gray}-1.455 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$14.5 \mathrm{ms} \pm 127 \mathrm{μs}\left({\color{gray}1.22 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 1527 $$24.6 \mathrm{ms} \pm 243 \mathrm{μs}\left({\color{gray}1.27 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 2078 $$28.7 \mathrm{ms} \pm 247 \mathrm{μs}\left({\color{gray}-0.926 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.73 \mathrm{ms} \pm 23.1 \mathrm{μs}\left({\color{gray}-1.103 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 1033 $$14.4 \mathrm{ms} \pm 112 \mathrm{μs}\left({\color{gray}1.89 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_medium

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 102 $$3.85 \mathrm{ms} \pm 26.3 \mathrm{μs}\left({\color{gray}-2.825 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.04 \mathrm{ms} \pm 23.8 \mathrm{μs}\left({\color{gray}-2.562 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 52 $$3.42 \mathrm{ms} \pm 21.3 \mathrm{μs}\left({\color{gray}-2.770 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 269 $$5.27 \mathrm{ms} \pm 33.0 \mathrm{μs}\left({\color{lightgreen}-7.416 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.61 \mathrm{ms} \pm 27.5 \mathrm{μs}\left({\color{gray}-1.268 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 108 $$4.19 \mathrm{ms} \pm 27.2 \mathrm{μs}\left({\color{lightgreen}-11.140 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 133 $$4.52 \mathrm{ms} \pm 33.5 \mathrm{μs}\left({\color{gray}-3.727 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.45 \mathrm{ms} \pm 24.0 \mathrm{μs}\left({\color{gray}-4.406 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 63 $$4.17 \mathrm{ms} \pm 36.9 \mathrm{μs}\left({\color{gray}-1.783 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_none

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2 $$2.79 \mathrm{ms} \pm 17.2 \mathrm{μs}\left({\color{gray}0.322 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.72 \mathrm{ms} \pm 14.0 \mathrm{μs}\left({\color{gray}1.30 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 2 $$2.89 \mathrm{ms} \pm 18.8 \mathrm{μs}\left({\color{gray}2.39 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 8 $$3.10 \mathrm{ms} \pm 19.6 \mathrm{μs}\left({\color{gray}0.730 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.90 \mathrm{ms} \pm 21.1 \mathrm{μs}\left({\color{gray}-0.777 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 3 $$3.22 \mathrm{ms} \pm 23.6 \mathrm{μs}\left({\color{gray}0.855 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_small

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 52 $$3.14 \mathrm{ms} \pm 21.2 \mathrm{μs}\left({\color{gray}-1.280 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.81 \mathrm{ms} \pm 15.0 \mathrm{μs}\left({\color{gray}-1.068 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 26 $$3.01 \mathrm{ms} \pm 21.7 \mathrm{μs}\left({\color{gray}1.03 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 94 $$3.56 \mathrm{ms} \pm 23.1 \mathrm{μs}\left({\color{gray}-1.593 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.09 \mathrm{ms} \pm 21.3 \mathrm{μs}\left({\color{gray}-1.111 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 27 $$3.33 \mathrm{ms} \pm 19.9 \mathrm{μs}\left({\color{gray}-0.627 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 66 $$3.49 \mathrm{ms} \pm 20.2 \mathrm{μs}\left({\color{lightgreen}-5.744 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.05 \mathrm{ms} \pm 12.0 \mathrm{μs}\left({\color{gray}-3.301 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 29 $$3.38 \mathrm{ms} \pm 24.9 \mathrm{μs}\left({\color{gray}-3.153 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_complete

Function Value Mean Flame graphs
entity_by_id;one_depth 1 entities $$31.8 \mathrm{ms} \pm 201 \mathrm{μs}\left({\color{gray}-0.388 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 10 entities $$70.7 \mathrm{ms} \pm 397 \mathrm{μs}\left({\color{gray}-0.622 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 25 entities $$34.6 \mathrm{ms} \pm 195 \mathrm{μs}\left({\color{gray}-2.144 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 5 entities $$39.6 \mathrm{ms} \pm 228 \mathrm{μs}\left({\color{gray}-0.248 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 50 entities $$41.4 \mathrm{ms} \pm 271 \mathrm{μs}\left({\color{gray}-0.418 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 1 entities $$33.7 \mathrm{ms} \pm 196 \mathrm{μs}\left({\color{gray}-0.547 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 10 entities $$425 \mathrm{ms} \pm 1.20 \mathrm{ms}\left({\color{gray}0.622 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 25 entities $$91.5 \mathrm{ms} \pm 566 \mathrm{μs}\left({\color{gray}0.174 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 5 entities $$80.5 \mathrm{ms} \pm 473 \mathrm{μs}\left({\color{gray}1.28 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 50 entities $$306 \mathrm{ms} \pm 1.39 \mathrm{ms}\left({\color{red}11.9 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 1 entities $$10.6 \mathrm{ms} \pm 65.4 \mathrm{μs}\left({\color{gray}-0.420 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 10 entities $$10.9 \mathrm{ms} \pm 74.8 \mathrm{μs}\left({\color{gray}1.06 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 25 entities $$10.9 \mathrm{ms} \pm 68.8 \mathrm{μs}\left({\color{gray}0.780 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 5 entities $$10.6 \mathrm{ms} \pm 61.5 \mathrm{μs}\left({\color{gray}-0.342 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 50 entities $$10.9 \mathrm{ms} \pm 78.0 \mathrm{μs}\left({\color{gray}2.22 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_linkless

Function Value Mean Flame graphs
entity_by_id 1 entities $$10.7 \mathrm{ms} \pm 77.8 \mathrm{μs}\left({\color{gray}3.19 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10 entities $$10.6 \mathrm{ms} \pm 74.8 \mathrm{μs}\left({\color{gray}-1.076 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 100 entities $$10.6 \mathrm{ms} \pm 73.3 \mathrm{μs}\left({\color{gray}0.386 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 1000 entities $$10.4 \mathrm{ms} \pm 63.7 \mathrm{μs}\left({\color{gray}-2.470 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10000 entities $$10.9 \mathrm{ms} \pm 65.6 \mathrm{μs}\left({\color{gray}-3.654 \mathrm{\%}}\right) $$ Flame Graph

representative_read_entity

Function Value Mean Flame graphs
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/block/v/1 $$11.1 \mathrm{ms} \pm 96.8 \mathrm{μs}\left({\color{gray}-3.974 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/book/v/1 $$11.4 \mathrm{ms} \pm 83.0 \mathrm{μs}\left({\color{gray}0.744 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/building/v/1 $$11.4 \mathrm{ms} \pm 62.5 \mathrm{μs}\left({\color{gray}-1.063 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/organization/v/1 $$11.2 \mathrm{ms} \pm 79.9 \mathrm{μs}\left({\color{gray}-4.790 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/page/v/2 $$11.4 \mathrm{ms} \pm 69.6 \mathrm{μs}\left({\color{gray}0.140 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/person/v/1 $$10.9 \mathrm{ms} \pm 77.4 \mathrm{μs}\left({\color{lightgreen}-5.896 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/playlist/v/1 $$11.4 \mathrm{ms} \pm 68.6 \mathrm{μs}\left({\color{gray}0.032 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/song/v/1 $$11.4 \mathrm{ms} \pm 74.6 \mathrm{μs}\left({\color{gray}0.405 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/uk-address/v/1 $$11.7 \mathrm{ms} \pm 87.4 \mathrm{μs}\left({\color{gray}0.553 \mathrm{\%}}\right) $$ Flame Graph

representative_read_entity_type

Function Value Mean Flame graphs
get_entity_type_by_id Account ID: bf5a9ef5-dc3b-43cf-a291-6210c0321eba $$8.22 \mathrm{ms} \pm 63.6 \mathrm{μs}\left({\color{gray}-4.148 \mathrm{\%}}\right) $$ Flame Graph

representative_read_multiple_entities

Function Value Mean Flame graphs
entity_by_property traversal_paths=0 0 $$57.4 \mathrm{ms} \pm 531 \mathrm{μs}\left({\color{lightgreen}-7.381 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$105 \mathrm{ms} \pm 645 \mathrm{μs}\left({\color{gray}-2.872 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$61.4 \mathrm{ms} \pm 628 \mathrm{μs}\left({\color{lightgreen}-9.116 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$69.2 \mathrm{ms} \pm 641 \mathrm{μs}\left({\color{lightgreen}-8.296 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$79.0 \mathrm{ms} \pm 550 \mathrm{μs}\left({\color{gray}-4.331 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$84.0 \mathrm{ms} \pm 566 \mathrm{μs}\left({\color{lightgreen}-5.764 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=0 0 $$43.8 \mathrm{ms} \pm 316 \mathrm{μs}\left({\color{gray}-4.745 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$72.2 \mathrm{ms} \pm 429 \mathrm{μs}\left({\color{gray}-3.284 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$50.2 \mathrm{ms} \pm 340 \mathrm{μs}\left({\color{lightgreen}-5.442 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$59.1 \mathrm{ms} \pm 471 \mathrm{μs}\left({\color{gray}-4.638 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$61.9 \mathrm{ms} \pm 638 \mathrm{μs}\left({\color{gray}-2.171 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$61.7 \mathrm{ms} \pm 492 \mathrm{μs}\left({\color{gray}-3.546 \mathrm{\%}}\right) $$

scenarios

Function Value Mean Flame graphs
full_test query-limited $$123 \mathrm{ms} \pm 608 \mathrm{μs}\left({\color{red}7.64 \mathrm{\%}}\right) $$ Flame Graph
full_test query-unlimited $$134 \mathrm{ms} \pm 679 \mathrm{μs}\left({\color{red}6.46 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-limited $$22.6 \mathrm{ms} \pm 149 \mathrm{μs}\left({\color{lightgreen}-9.417 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-unlimited $$540 \mathrm{ms} \pm 1.87 \mathrm{ms}\left({\color{gray}-1.266 \mathrm{\%}}\right) $$ Flame Graph

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/apps area/deps Relates to third-party dependencies (area) area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) area/tests New or updated tests type/eng > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

4 participants